import * as ExcelJS from 'exceljs'
import { ExportEngine, ExportType, ExportData, ExportOptions, ExportProgress } from './types'

/**
 * Excel导出引擎
 * 使用ExcelJS生成结构化的分镜数据表格
 */
export class ExcelExportEngine implements ExportEngine {
  type = ExportType.EXCEL
  
  /**
   * 生成Excel文件
   */
  async generate(
    data: ExportData,
    options: ExportOptions,
    onProgress?: (progress: ExportProgress) => void
  ): Promise<Blob> {
    try {
      onProgress?.({
        stage: 'preparing',
        progress: 0,
        message: '准备生成Excel文件...'
      })
      
      // 创建工作簿
      const workbook = new ExcelJS.Workbook()
      workbook.creator = '融媒智创工坊'
      workbook.created = new Date()
      
      onProgress?.({
        stage: 'processing',
        progress: 20,
        message: '创建场景数据表...'
      })
      
      // 创建场景数据工作表
      await this.createScenesWorksheet(workbook, data, options)
      
      onProgress?.({
        stage: 'processing',
        progress: 60,
        message: '创建统计信息表...'
      })
      
      // 创建统计信息工作表
      if (options.includeStatistics) {
        await this.createStatisticsWorksheet(workbook, data)
      }
      
      onProgress?.({
        stage: 'processing',
        progress: 80,
        message: '创建镜头类型汇总...'
      })
      
      // 创建镜头类型汇总表
      await this.createShotTypeSummaryWorksheet(workbook, data)
      
      onProgress?.({
        stage: 'finalizing',
        progress: 90,
        message: '生成Excel文件...'
      })
      
      // 生成Buffer并转换为Blob
      const buffer = await workbook.xlsx.writeBuffer()
      const blob = new Blob([buffer], {
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      })
      
      onProgress?.({
        stage: 'completed',
        progress: 100,
        message: 'Excel文件生成完成'
      })
      
      return blob
      
    } catch (error) {
      onProgress?.({
        stage: 'error',
        progress: 0,
        message: '生成Excel文件时发生错误',
        error: error instanceof Error ? error.message : String(error)
      })
      throw error
    }
  }
  
  /**
   * 创建场景数据工作表
   */
  private async createScenesWorksheet(
    workbook: ExcelJS.Workbook,
    data: ExportData,
    options: ExportOptions
  ): Promise<void> {
    const worksheet = workbook.addWorksheet('分镜场景清单')
    
    // 设置列定义
    worksheet.columns = [
      { header: '场景编号', key: 'order', width: 10 },
      { header: '场景标题', key: 'title', width: 20 },
      { header: '场景描述', key: 'description', width: 30 },
      { header: '时长(秒)', key: 'duration', width: 10 },
      { header: '镜头类型', key: 'shotType', width: 12 },
      { header: '拍摄角度', key: 'cameraAngle', width: 12 },
      { header: '镜头运动', key: 'cameraMovement', width: 12 },
      { header: '拍摄地点', key: 'location', width: 15 },
      { header: '场景类型', key: 'locationType', width: 10 },
      { header: '光线条件', key: 'lighting', width: 12 },
      { header: '出场人物', key: 'characters', width: 20 },
      { header: '相关道具', key: 'props', width: 20 },
      { header: '优先级', key: 'priority', width: 10 },
      { header: '复杂度', key: 'complexity', width: 10 },
      { header: '制作备注', key: 'notes', width: 25 }
    ]
    
    // 设置表头样式
    const headerRow = worksheet.getRow(1)
    headerRow.font = { bold: true }
    headerRow.fill = {
      type: 'pattern',
      pattern: 'solid',
      fgColor: { argb: 'FFE6F3FF' }
    }
    headerRow.border = {
      top: { style: 'thin' },
      left: { style: 'thin' },
      bottom: { style: 'thin' },
      right: { style: 'thin' }
    }
    
    // 添加数据行
    const scenesToExport = options.includeAll
      ? data.scenes
      : data.scenes.filter(scene => options.selectedSceneIds?.includes(scene.id))
    
    scenesToExport.forEach((scene, index) => {
      const row = worksheet.addRow({
        order: scene.order + 1,
        title: scene.title,
        description: scene.description,
        duration: scene.duration,
        shotType: scene.shotType,
        cameraAngle: scene.cameraAngle,
        cameraMovement: scene.cameraMovement || '静止',
        location: scene.location,
        locationType: scene.locationType,
        lighting: scene.lighting,
        characters: scene.characters.join(', '),
        props: scene.props.join(', '),
        priority: scene.priority,
        complexity: scene.complexity,
        notes: scene.notes || ''
      })
      
      // 设置数据行样式
      row.border = {
        top: { style: 'thin' },
        left: { style: 'thin' },
        bottom: { style: 'thin' },
        right: { style: 'thin' }
      }
      
      // 交替行颜色
      if (index % 2 === 1) {
        row.fill = {
          type: 'pattern',
          pattern: 'solid',
          fgColor: { argb: 'FFF8F8F8' }
        }
      }
    })
    
    // 添加数据验证
    this.addDataValidation(worksheet, scenesToExport.length)
    
    // 自动筛选
    worksheet.autoFilter = {
      from: 'A1',
      to: `O${scenesToExport.length + 1}`
    }
  }
  
  /**
   * 创建统计信息工作表
   */
  private async createStatisticsWorksheet(
    workbook: ExcelJS.Workbook,
    data: ExportData
  ): Promise<void> {
    const worksheet = workbook.addWorksheet('统计信息')
    const { statistics, projectInfo } = data
    
    // 项目基本信息
    worksheet.addRow(['项目信息'])
    worksheet.addRow(['项目名称', projectInfo.title])
    worksheet.addRow(['创建时间', projectInfo.createdAt.toLocaleDateString()])
    worksheet.addRow(['项目描述', projectInfo.description || ''])
    worksheet.addRow([])
    
    // 基础统计
    worksheet.addRow(['基础统计'])
    worksheet.addRow(['总场景数', statistics.totalScenes])
    worksheet.addRow(['总时长(秒)', statistics.totalDuration])
    worksheet.addRow(['总时长(分钟)', Math.round(statistics.totalDuration / 60 * 100) / 100])
    worksheet.addRow(['平均时长(秒)', Math.round(statistics.averageDuration * 100) / 100])
    
    if (statistics.longestScene) {
      worksheet.addRow(['最长场景', statistics.longestScene.title])
      worksheet.addRow(['最长时长(秒)', statistics.longestScene.duration])
    }
    
    if (statistics.shortestScene) {
      worksheet.addRow(['最短场景', statistics.shortestScene.title])
      worksheet.addRow(['最短时长(秒)', statistics.shortestScene.duration])
    }
    
    worksheet.addRow([])
    
    // 场景要素统计
    worksheet.addRow(['场景要素'])
    worksheet.addRow(['拍摄地点数', statistics.locationCount])
    worksheet.addRow(['出场人物数', statistics.characterCount])
    worksheet.addRow([])
    
    // 镜头类型统计
    worksheet.addRow(['镜头类型分布'])
    Object.entries(statistics.scenesByType).forEach(([type, count]) => {
      worksheet.addRow([type, count])
    })
    
    // 设置样式
    this.setStatisticsWorksheetStyle(worksheet)
  }
  
  /**
   * 创建镜头类型汇总工作表
   */
  private async createShotTypeSummaryWorksheet(
    workbook: ExcelJS.Workbook,
    data: ExportData
  ): Promise<void> {
    const worksheet = workbook.addWorksheet('镜头类型汇总')
    
    // 创建透视表样式的汇总
    const shotTypeGroups: Record<string, any[]> = {}
    
    data.scenes.forEach(scene => {
      const shotType = scene.shotType
      if (!shotTypeGroups[shotType]) {
        shotTypeGroups[shotType] = []
      }
      shotTypeGroups[shotType].push(scene)
    })
    
    // 表头
    worksheet.addRow(['镜头类型', '场景数量', '总时长(秒)', '平均时长(秒)', '场景列表'])
    
    const headerRow = worksheet.getRow(1)
    headerRow.font = { bold: true }
    headerRow.fill = {
      type: 'pattern',
      pattern: 'solid',
      fgColor: { argb: 'FFE6F3FF' }
    }
    
    // 数据行
    Object.entries(shotTypeGroups).forEach(([shotType, scenes]) => {
      const totalDuration = scenes.reduce((sum, scene) => sum + scene.duration, 0)
      const avgDuration = totalDuration / scenes.length
      const sceneList = scenes.map(scene => scene.title).join(', ')
      
      worksheet.addRow([
        shotType,
        scenes.length,
        Math.round(totalDuration * 100) / 100,
        Math.round(avgDuration * 100) / 100,
        sceneList
      ])
    })
    
    // 设置列宽
    worksheet.getColumn(1).width = 15
    worksheet.getColumn(2).width = 12
    worksheet.getColumn(3).width = 15
    worksheet.getColumn(4).width = 15
    worksheet.getColumn(5).width = 40
  }
  
  /**
   * 添加数据验证
   */
  private addDataValidation(worksheet: ExcelJS.Worksheet, dataRowCount: number): void {
    // 优先级下拉选项
    const priorityCol = worksheet.getColumn('priority')
    for (let i = 2; i <= dataRowCount + 1; i++) {
      const cell = priorityCol.getCell(i)
      cell.dataValidation = {
        type: 'list',
        allowBlank: false,
        formulae: ['"低,普通,高,紧急"']
      }
    }
    
    // 复杂度下拉选项
    const complexityCol = worksheet.getColumn('complexity')
    for (let i = 2; i <= dataRowCount + 1; i++) {
      const cell = complexityCol.getCell(i)
      cell.dataValidation = {
        type: 'list',
        allowBlank: false,
        formulae: ['"简单,中等,复杂"']
      }
    }
  }
  
  /**
   * 设置统计信息工作表样式
   */
  private setStatisticsWorksheetStyle(worksheet: ExcelJS.Worksheet): void {
    // 设置列宽
    worksheet.getColumn(1).width = 20
    worksheet.getColumn(2).width = 25
    
    // 设置标题样式
    worksheet.eachRow((row, rowNumber) => {
      const firstCell = row.getCell(1)
      const value = firstCell.value as string
      
      if (value && ['项目信息', '基础统计', '场景要素', '镜头类型分布'].includes(value)) {
        row.font = { bold: true, size: 14 }
        row.fill = {
          type: 'pattern',
          pattern: 'solid',
          fgColor: { argb: 'FFEEF2FF' }
        }
      }
    })
  }
  
  /**
   * 获取支持的导出选项
   */
  getSupportedOptions(): Partial<ExportOptions> {
    return {
      includeStatistics: true,
      includeTechnicalParams: true,
      includeNotes: true
    }
  }
}